Upload dependency kinds to the registry
authorAlex Crichton <alex@alexcrichton.com>
Fri, 21 Nov 2014 02:17:31 +0000 (18:17 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 24 Nov 2014 23:33:29 +0000 (15:33 -0800)
This ensures that the registry understands whether dependencies are build
dependencies or dev dependencies.

Closes rust-lang/crates.io#38

src/cargo/core/dependency.rs
src/cargo/ops/registry.rs
src/cargo/sources/registry.rs
src/registry/lib.rs
tests/support/registry.rs
tests/test_cargo_registry.rs

index 14935f7d0541a94b5ea3cd74c1a5bcf38938dedb..97a2dc71cde06664e153f2676a0b13e9269261d1 100644 (file)
@@ -90,6 +90,8 @@ impl Dependency {
         &self.source_id
     }
 
+    pub fn get_kind(&self) -> Kind { self.kind }
+
     pub fn kind(mut self, kind: Kind) -> Dependency {
         self.kind = kind;
         self
index e0bfc63b4f9801eb30dbfd749ce31166604d544f..e042d0765b12cfe96ef2e6a3849aff2ce0960756 100644 (file)
@@ -9,6 +9,7 @@ use registry::{Registry, NewCrate, NewCrateDependency};
 
 use core::source::Source;
 use core::{Package, MultiShell, SourceId};
+use core::dependency::Kind;
 use core::manifest::ManifestMetadata;
 use ops;
 use sources::{PathSource, RegistrySource};
@@ -76,6 +77,11 @@ fn transmit(pkg: &Package, tarball: &Path, registry: &mut Registry)
             features: dep.get_features().to_vec(),
             version_req: dep.get_version_req().to_string(),
             target: dep.get_only_for_platform().map(|s| s.to_string()),
+            kind: match dep.get_kind() {
+                Kind::Normal => "normal",
+                Kind::Build => "build",
+                Kind::Development => "dev",
+            }.to_string(),
         }
     }).collect::<Vec<NewCrateDependency>>();
     let manifest = pkg.get_manifest();
index bea14aa85165823afbbc60375964b581fc9a92da..770259c58c4cf2b3e7b09180d9b1ef44044365ec 100644 (file)
@@ -171,7 +171,7 @@ use tar::Archive;
 use url::Url;
 
 use core::{Source, SourceId, PackageId, Package, Summary, Registry};
-use core::Dependency;
+use core::dependency::{Dependency, Kind};
 use sources::{PathSource, git};
 use util::{CargoResult, Config, internal, ChainError, ToUrl, human};
 use util::{hex, Require, Sha256};
@@ -222,6 +222,7 @@ struct RegistryDependency {
     optional: bool,
     default_features: bool,
     target: Option<String>,
+    kind: Option<String>,
 }
 
 impl<'a, 'b> RegistrySource<'a, 'b> {
@@ -412,16 +413,22 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
     fn parse_registry_dependency(&self, dep: RegistryDependency)
                                  -> CargoResult<Dependency> {
         let RegistryDependency {
-            name, req, features, optional, default_features, target
+            name, req, features, optional, default_features, target, kind
         } = dep;
 
         let dep = try!(Dependency::parse(name.as_slice(), Some(req.as_slice()),
                                          &self.source_id));
+        let kind = match kind.as_ref().map(|s| s.as_slice()).unwrap_or("") {
+            "dev" => Kind::Development,
+            "build" => Kind::Build,
+            _ => Kind::Normal,
+        };
 
         Ok(dep.optional(optional)
               .default_features(default_features)
               .features(features)
-              .only_for_platform(target))
+              .only_for_platform(target)
+              .kind(kind))
     }
 
     /// Actually perform network operations to update the registry
index 0e5be48fe94ea6bcd304a285195a159ee185a110..39f5965a765aefae074070e1cb709bfa8cd7a2e0 100644 (file)
@@ -66,6 +66,7 @@ pub struct NewCrateDependency {
     pub features: Vec<String>,
     pub version_req: String,
     pub target: Option<String>,
+    pub kind: String,
 }
 
 #[deriving(Decodable)]
index 8306d49896bfd004d3bb23f5b31dc849e7a7b752..0069343980931a1b9bf5892b0d67f6d5e141ddf8 100644 (file)
@@ -34,18 +34,22 @@ pub fn init() {
         .build();
 }
 
-pub fn mock_archive(name: &str, version: &str, deps: &[(&str, &str)]) {
+pub fn mock_archive(name: &str, version: &str, deps: &[(&str, &str, &str)]) {
     let mut manifest = format!(r#"
         [package]
         name = "{}"
         version = "{}"
         authors = []
     "#, name, version);
-    for &(dep, req) in deps.iter() {
+    for &(dep, req, kind) in deps.iter() {
         manifest.push_str(format!(r#"
-            [dependencies.{}]
+            [{}dependencies.{}]
             version = "{}"
-        "#, dep, req).as_slice());
+        "#, match kind {
+            "build" => "build-",
+            "dev" => "dev-",
+            _ => ""
+        }, dep, req).as_slice());
     }
     let p = project(name)
         .file("Cargo.toml", manifest.as_slice())
@@ -67,11 +71,11 @@ pub fn mock_archive_dst(name: &str, version: &str) -> Path {
     dl_path().join(name).join(version).join("download")
 }
 
-pub fn mock_pkg(name: &str, version: &str, deps: &[(&str, &str)]) {
+pub fn mock_pkg(name: &str, version: &str, deps: &[(&str, &str, &str)]) {
     mock_pkg_yank(name, version, deps, false)
 }
 
-pub fn mock_pkg_yank(name: &str, version: &str, deps: &[(&str, &str)],
+pub fn mock_pkg_yank(name: &str, version: &str, deps: &[(&str, &str, &str)],
                      yanked: bool) {
     mock_archive(name, version, deps);
     let c = File::open(&mock_archive_dst(name, version)).read_to_end().unwrap();
@@ -107,22 +111,23 @@ pub fn publish(file: &str, line: &str) {
                 &[&parent]).unwrap();
 }
 
-pub fn pkg(name: &str, vers: &str, deps: &[(&str, &str)], cksum: &str,
+pub fn pkg(name: &str, vers: &str, deps: &[(&str, &str, &str)], cksum: &str,
            yanked: bool) -> String {
-    let deps = deps.iter().map(|&(a, b)| dep(a, b)).collect::<Vec<String>>();
+    let deps = deps.iter().map(|&(a, b, c)| dep(a, b, c)).collect::<Vec<String>>();
     format!("{{\"name\":\"{}\",\"vers\":\"{}\",\
                \"deps\":{},\"cksum\":\"{}\",\"features\":{{}},\
                \"yanked\":{}}}",
             name, vers, deps, cksum, yanked)
 }
 
-pub fn dep(name: &str, req: &str) -> String {
+pub fn dep(name: &str, req: &str, kind: &str) -> String {
     format!("{{\"name\":\"{}\",\
                \"req\":\"{}\",\
                \"features\":[],\
                \"default_features\":false,\
                \"target\":null,\
-               \"optional\":false}}", name, req)
+               \"optional\":false,\
+               \"kind\":\"{}\"}}", name, req, kind)
 }
 
 pub fn cksum(s: &[u8]) -> String {
index 585bfc444c2862a82408fbd0c229072a7196c554..a9aa06f168948e72c36e1539b3568ab38e41c69b 100644 (file)
@@ -65,7 +65,7 @@ test!(deps {
         .file("src/main.rs", "fn main() {}");
 
     r::mock_pkg("baz", "0.0.1", &[]);
-    r::mock_pkg("bar", "0.0.1", &[("baz", "*")]);
+    r::mock_pkg("bar", "0.0.1", &[("baz", "*", "normal")]);
 
     assert_that(p.cargo_process("build"),
                 execs().with_status(0).with_stdout(format!("\
@@ -269,7 +269,7 @@ test!(lockfile_locks_transitively {
     p.build();
 
     r::mock_pkg("baz", "0.0.1", &[]);
-    r::mock_pkg("bar", "0.0.1", &[("baz", "*")]);
+    r::mock_pkg("bar", "0.0.1", &[("baz", "*", "normal")]);
 
     assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
                 execs().with_status(0).with_stdout(format!("\
@@ -284,7 +284,7 @@ test!(lockfile_locks_transitively {
 
     p.root().move_into_the_past().unwrap();
     r::mock_pkg("baz", "0.0.2", &[]);
-    r::mock_pkg("bar", "0.0.2", &[("baz", "*")]);
+    r::mock_pkg("bar", "0.0.2", &[("baz", "*", "normal")]);
 
     assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
                 execs().with_status(0).with_stdout(""));
@@ -306,8 +306,8 @@ test!(yanks_are_not_used {
 
     r::mock_pkg("baz", "0.0.1", &[]);
     r::mock_pkg_yank("baz", "0.0.2", &[], true);
-    r::mock_pkg("bar", "0.0.1", &[("baz", "*")]);
-    r::mock_pkg_yank("bar", "0.0.2", &[("baz", "*")], true);
+    r::mock_pkg("bar", "0.0.1", &[("baz", "*", "normal")]);
+    r::mock_pkg_yank("bar", "0.0.2", &[("baz", "*", "normal")], true);
 
     assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
                 execs().with_status(0).with_stdout(format!("\
@@ -337,7 +337,7 @@ test!(relying_on_a_yank_is_bad {
 
     r::mock_pkg("baz", "0.0.1", &[]);
     r::mock_pkg_yank("baz", "0.0.2", &[], true);
-    r::mock_pkg("bar", "0.0.1", &[("baz", "=0.0.2")]);
+    r::mock_pkg("bar", "0.0.1", &[("baz", "=0.0.2", "normal")]);
 
     assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
                 execs().with_status(101).with_stderr("\
@@ -442,3 +442,30 @@ test!(update_lockfile {
 ", downloading = DOWNLOADING, compiling = COMPILING,
    dir = p.url()).as_slice()));
 })
+
+test!(dev_dependency_not_used {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [project]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies]
+            bar = "*"
+        "#)
+        .file("src/main.rs", "fn main() {}");
+    p.build();
+
+    r::mock_pkg("baz", "0.0.1", &[]);
+    r::mock_pkg("bar", "0.0.1", &[("baz", "*", "dev")]);
+
+    assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
+                execs().with_status(0).with_stdout(format!("\
+{updating} registry `[..]`
+{downloading} [..] v0.0.1 (registry file://[..])
+{compiling} bar v0.0.1 (registry file://[..])
+{compiling} foo v0.0.1 ({dir})
+", updating = UPDATING, downloading = DOWNLOADING, compiling = COMPILING,
+   dir = p.url()).as_slice()));
+})